#define DEBUG
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn=250, dir[][2]={{-1, 0}, {0, -1}, {0, 1}, {1, 0}};

class Set {
public:
  int fa[maxn*maxn+1], size[maxn*maxn+1], ver[maxn*maxn+1];

  void init() {
    ver[0]++;
  }

  int getFa(int o) {
    if (ver[o]!=ver[0]) {
      fa[o] = o, size[o] = 1, ver[o] = ver[0];
    }
    if (fa[o]!=o) {
      size[fa[o]] += size[o], size[o] = 0;
      fa[o] = getFa(fa[o]);
    }
    return fa[o];
  }

  int getFa(int o, int init[]) {
    if (ver[o]!=ver[0]) {
      fa[o] = o, size[o] = init[o], ver[o] = ver[0];
    }
    if (fa[o]!=o) {
      size[fa[o]] += size[o], size[o] = 0;
      fa[o] = getFa(fa[o]);
    }
    return fa[o];
  }

  void merge(int u, int v) {
    u = getFa(u), v = getFa(v);
    if (u!=v) {
      fa[v] = u;
    }
  }

  void merge(int u, int v, int init[]) {
    u = getFa(u, init), v = getFa(v, init);
    if (u!=v) {
      fa[v] = u;
    }
  }
};

class Side {
public:
  int a, b, x, y;

  void init(int u, int v, int m, int n) {
    a=u, b=v, x=min(m, n), y=max(m, n);
  }

  static bool cmp(Side &a, Side &b) {
    return a.x<b.x || (a.x==b.x && a.y<b.y);
  }
};

int main() {
  freopen("multimoo.in", "r", stdin);
  freopen("multimoo.out", "w", stdout);

  static int map[maxn+1][maxn+1];
  int n;
  scanf("%d", &n);
  for (int i=1; i<=n; i++) {
    for (int j=1; j<=n; j++) {
      scanf("%d", &map[i][j]);
    }
  }

  static Set set, set2;
  static Side sides[4*maxn*maxn+1];
  int ans1=0, ans2=0, sn=0;
  set.init();
  for (int i=1; i<=n; i++) {
    for (int j=1; j<=n; j++) {
      for (int k=0; k<4; k++) {
        int x=i+dir[k][0], y=j+dir[k][1];
        if (x && y && x<=n && y<=n && map[x][y]==map[i][j]) {
          set.merge(x*n+y-n, i*n+j-n);
        }
      }
    }
  }
  
  for (int i=1; i<=n; i++) {
    for (int j=1; j<=n; j++) {
      ans1 = max(ans1, set.size[set.getFa(i*n+j-n)]);
      for (int k=0; k<4; k++) {
        int x=i+dir[k][0], y=j+dir[k][1];
        if (x && y && x<=n && y<=n && map[x][y]!=map[i][j]) {
          sides[++sn].init(set.getFa(x*n+y-n), set.getFa(i*n+j-n), map[x][y], map[i][j]);
        }
      }
    }
  }
  sort(sides+1, sides+sn+1, Side::cmp);
  for (int i=1, j; i<=sn; ) {
    set2.init();
    for (j=i; j<=sn && sides[i].x==sides[j].x && sides[i].y==sides[j].y; j++) {
      set2.merge(sides[j].a, sides[j].b, set.size);
      set2.getFa(sides[j].a, set.size), set2.getFa(sides[j].b, set.size);
      ans2 = max(ans2, set2.size[set2.getFa(sides[j].a, set.size)]);
    }
    i = j;
  }

  printf("%d\n%d", ans1, ans2);

  fclose(stdin);
  fclose(stdout);
  return 0;
}
